﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using ControleRepresentanteSync.Logic.Models;
using ExcelLibrary;

namespace ControleRepresentanteSync.Logic
{
    internal class JolitexContentHandler : IJolitexRetriever
    {
        private readonly ISyncServiceProvider m_SyncServiceProvider;
        private readonly IEnumerable<string> m_PedidoFilePaths;

        public JolitexContentHandler(ISyncServiceProvider syncServiceProvider, IEnumerable<string> pedidoFilePathses)
        {
            m_SyncServiceProvider = syncServiceProvider;
            m_PedidoFilePaths = pedidoFilePathses;
        }

        private IEnumerable<string> GetNotSynchronizedPedidos(IEnumerable<string> pedidos)
        {
            return m_SyncServiceProvider.Execute(syncService => syncService.FilterSynchronizedPedidos(pedidos.ToArray()));
        }


        public IEnumerable<Pedido> GetPedidos(out string error)
        {
            List<Pedido> pedidos = new List<Pedido>();
            List<string> errorPaths = new List<string>();

            foreach (string pedidoFilePath in m_PedidoFilePaths)
            {
                try
                {
                    DataTable dataTable = DataSetHelper.CreateDataSet(pedidoFilePath).Tables[0];

                    List<Produto> produtos = new List<Produto>();
                    int i;
                    for (i = 15; !String.IsNullOrEmpty((string)dataTable.Rows[i][1]); i++)
                    {
                        produtos.Add(new Produto
                        {
                            Codigo = (string)dataTable.Rows[i][1],
                            Descricao = (string)dataTable.Rows[i][2],
                            Quantidade = Convert.ToInt32(dataTable.Rows[i][5]),
                            PrecoUnitario = Convert.ToDouble(dataTable.Rows[i][10])
                        });
                    }
                    double valorDesconto = Convert.ToDouble(dataTable.Rows[i + 2][7]);
                    string transportadora = (string)dataTable.Rows[9][3];
                    pedidos.Add(new Pedido
                    {
                        Data =
                            DateTime.ParseExact(((string)dataTable.Rows[3][3]).Trim().Substring(0, 10), "dd/MM/yyyy",
                                CultureInfo.InvariantCulture).Date,
                        CodigoCliente = Convert.ToInt32(dataTable.Rows[7][1]),
                        CodigoTransportadora = String.IsNullOrEmpty(transportadora) ? (int?)null : Convert.ToInt32(transportadora.Split(' ')[0]),
                        CondicaoPagamento = (string)dataTable.Rows[4][5],
                        Desconto = 100 * valorDesconto / produtos.Sum(x => x.PrecoUnitario * x.Quantidade),
                        ValorDesconto = valorDesconto,
                        Numero = (string)dataTable.Rows[3][1],
                        Observacao = (string)dataTable.Rows[11][1],
                        PrazoEntrega =
                            DateTime.ParseExact(((string)dataTable.Rows[4][3]).Trim().Substring(0, 10), "dd/MM/yyyy",
                                CultureInfo.InvariantCulture).Date,
                        Produtos = produtos.ToArray(),
                        ValorImposto = Convert.ToDouble(dataTable.Rows[i + 2][9]),
                        TotalMercadoria = Convert.ToDouble(dataTable.Rows[i + 2][11]),
                        TotalLiquido = Convert.ToDouble(dataTable.Rows[i + 2][10]),
                        OCCliente = (string)dataTable.Rows[5][1]
                    });
                }
                catch
                {
                    errorPaths.Add(pedidoFilePath);
                }
            }
            IEnumerable<string> notSynchronizedPedidos = GetNotSynchronizedPedidos(pedidos.Select(x => x.Numero));
            pedidos = pedidos.Where(x => notSynchronizedPedidos.Contains(x.Numero)).ToList();

            error = errorPaths.Any() ? String.Join(", ", errorPaths.ToArray()) : null;
            return pedidos;
        }
    }
}